home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / Drop•MPSR / Spinning Cursor Lib ƒ / SpinLib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-03  |  4.6 KB  |  205 lines  |  [TEXT/KAHL]

  1. /*
  2.     SpinLib.c
  3.     
  4.     Code for spinning a beachball cursor.
  5. */
  6.  
  7. #include "SpinLibInterns.h"
  8.  
  9. #include <Traps.h>
  10. #include <GestaltEqu.h>
  11. #include <Think.h>
  12.  
  13. #ifndef CrsrBusy
  14. #define CrsrBusy  0x8CD                /*[GLOBAL VAR]  Cursor locked out? [byte]*/
  15. #endif
  16.  
  17.  
  18. pascal long __GetVBLRec (void);
  19. pascal long __GetVBLRec (void)
  20.     = 0x2E88;
  21.  
  22. CursorTask            gCursTask;                        /* Global structure */
  23. Boolean                gCursInstalled = false;                /* installation global */
  24. Boolean                gCursInited=false;
  25.  
  26. /*
  27.     SpinInit
  28.     
  29.     Loads the cursors and sets up the spinning stuff...
  30. */
  31. OSErr SpinInit(void){
  32.     Handle h;
  33.     short i;
  34.     OSErr err;
  35.     
  36.     if (gCursInited)
  37.         return noErr;
  38.         
  39.     gCursInstalled = false;                            /* we are not installed yet */
  40.     gCursInited=false;
  41.     
  42.     /* allocate cursor memory */
  43.     gCursTask.cursors=(CursHandle *)NewPtr (8*sizeof (CursHandle));
  44.     
  45.     gCursTask.value=0;
  46.     
  47.     for (i=0; i < 8; i++) {                            /* cycle through the rest */
  48.             
  49.         h = (Handle)GetCursor (128+i);                    /* black and white */
  50.             
  51.         if (h == nil)                                /* did we get the cursor */
  52.             return ResError();                        /* if no, return error */
  53.         
  54.         DetachResource(h);
  55.         HNoPurge (h);                                /* force it unpurgeable */
  56.         HLockHi (h);                                /* and lock it high */
  57.         
  58.         gCursTask.cursors[i]=(CursHandle)h;
  59.     }
  60.     
  61.     gCursInited=true;
  62.     
  63.     return noErr;
  64. }
  65.  
  66. /*
  67.     SpinStart
  68.     
  69.     Starts the spinning of the beachball.
  70. */
  71. OSErr SpinStart(short direction){
  72.     OSErr        err;                                    /* returnable error */
  73.     short        i;                                    /* dummy counter */
  74.     Handle        h;
  75.     
  76.     if (!gCursInited)
  77.         return paramErr;
  78.         
  79.     if (gCursInstalled)                                    /* if we are already installed, */
  80.         return noErr; // do nothing...
  81.             
  82.     if (direction==0)
  83.         direction=1;
  84.     
  85.     if (direction>1)
  86.         direction=1;
  87.     if (direction<-1)
  88.         direction=-1;
  89.         
  90.     gCursTask.direction=direction;
  91.     
  92.     gCursTask.vblTask.qType = vType;                        /* set up the VBL task record */
  93.     gCursTask.vblTask.vblAddr = (ProcPtr)SpinTask;
  94.     gCursTask.vblTask.vblCount = 20;
  95.     gCursTask.vblTask.vblPhase = 0;
  96.     gCursTask.vblA5 = SetCurrentA5();
  97.     
  98.     err = VInstall ((QElemPtr)&gCursTask.vblTask);            /* install the VBL task */
  99.         
  100.     if (err)
  101.         return err;                                    /* if errors, return them, else */
  102.     else {
  103.         gCursInstalled = true;                            /* declare the task installed */
  104.         return noErr;                                    /* and return no error */
  105.     }
  106. }
  107.  
  108. /*
  109.     SpinTask
  110.     
  111.     This is the meat and bones of the spinning cursor calls.  When the VBL task count (vblCount) goes to zero, the
  112.     Vertical Retrace Manager will call SpinCursor(). Our job will be to set the cursor to the current frame, and then
  113.     to advance the frame. The thing to remember is that we are executed during interrupt, and we are not allowed to
  114.     use Memory Manager calls... as well as a billion other things.
  115.     
  116.     Another cool thing to note is that at the time of our interrupt, a pointer to the installed VBL task will be
  117.     placed in A0. Since we installed with some more globals attached, these will also be available to us; kind of
  118.     a sneaky way around the messed up A5 problem.
  119.     
  120.     Also remember that the vblCount is zero at this time. If we leave this function without returning a nonzero value,
  121.     the task will never return to SpinCursor again. So, we articulately return the vblCount to frequency, which is
  122.     why the task happens so regulary...
  123. */
  124. pascal void SpinTask(void){
  125.     CursorTaskPtr        taskPtr;
  126.     Boolean            busy;
  127.     CursPtr            cp;
  128.     
  129.     taskPtr=(CursorTaskPtr)__GetVBLRec();
  130.     
  131.     busy = (*(Boolean *)CrsrBusy);                        /* determine the cursor state */
  132.         
  133.     if (!busy) {                                        /* if it is available to us */
  134.                                                     /* set the cursor and frame advance */
  135.         cp=(CursPtr)(*(taskPtr->cursors[taskPtr->value]));
  136.         
  137.         SetCursor(cp);
  138.         
  139.         taskPtr->value += taskPtr->direction;
  140.             
  141.         if (taskPtr->value>7)
  142.             taskPtr->value=0;
  143.         
  144.         if (taskPtr->value<0)
  145.             taskPtr->value=7;
  146.     }
  147.  
  148.     taskPtr->vblTask.vblCount = 3;        /* restore the VBL task */
  149. }
  150.  
  151. /*
  152.     SpinStop
  153.     
  154.     Stops the spinning of the cursor.
  155. */
  156. OSErr SpinStop(void){
  157.     OSErr        err;
  158.     short        i;
  159.             
  160.     if (!gCursInstalled)                                    /* if we were not installed, */
  161.         return noErr;                                    /* alert them and exit */
  162.     
  163.     err = VRemove ((QElemPtr)&gCursTask.vblTask);            /* remove the VBL task */
  164.     gCursInstalled=false;
  165.     
  166.     SetCursor (&arrow);                                /* restore the cursor to an arrow */
  167.     
  168.     return err;
  169. }
  170.  
  171. /*
  172.     SpinSpinning
  173.     
  174.     returns state of the cursor.
  175. */
  176. Boolean SpinSpinning(void){
  177.     return gCursInstalled;
  178. }
  179.  
  180. /*
  181.     SpinCleanup
  182.     
  183.     Dispose of the memory being used by the spinning cursors...
  184. */
  185. OSErr SpinCleanup(void){
  186.     short i;
  187.     OSErr err;
  188.     
  189.     if (gCursInstalled)
  190.         SpinStop();
  191.     
  192.     if (!gCursInited)
  193.         return noErr;
  194.         
  195.     for (i=0;i<8;i++){
  196.         HUnlock((Handle)(gCursTask.cursors[i]));
  197.         HPurge((Handle)(gCursTask.cursors[i]));
  198.         DisposeHandle((Handle)gCursTask.cursors[i]);
  199.     }
  200.     
  201.     DisposePtr((Ptr)(gCursTask.cursors));
  202.     
  203.     return noErr;                                        /* and return no error */
  204. }
  205.